我在一个拥有12个内核的系统上运行了几个Haskell进程.所有进程都-threaded
使用12种功能进行编译和运行.他们都使用的一个库resource-pool
保存了一个数据库连接池.
有趣的是,即使所有进程实际上都处于空闲状态,它们也会占用大约2%的CPU时间.检查这些进程之一strace -p $(pgrep processname) -f
表明该进程正在进行不合理的系统调用,即使它实际上不应该做任何事情.把事情放到透视中:
在进程上运行strace -N2
5秒会生成66K日志文件.
运行它(不合理)会-N64
产生60 兆字节的日志.
因此,功能的数量会增加大量发布的系统调用量.
深入挖掘,我们发现resource-pool
正在运行一个收割机线程,它会每秒触发一次,以检查它是否可以清理一些资源.我们可以用这个简单的程序模拟相同的行为.
module Main where import Control.Concurrent import Control.Monad (forever) main :: IO () main = forever $ do threadDelay (10 ^ 6)
如果我传递-B
给运行时系统,每当发出GC时我都会得到音频反馈,在这种情况下每隔60秒就会发出一次.
因此,当我通过传递-I0
给RTS来抑制这些GC周期时,strace
在该进程上运行命令只会产生大约70K的大型日志文件.由于该进程也在运行scotty
服务器,因此在请求进入时会触发GC,因此它们似乎在我真正需要它时发生.
由于我们将在明年的过程中大量增加这台机器上的Haskell进程数量,我想知道如何将它们的空闲时间保持在合理的水平.显然,过往-I0
似乎是一个相当糟糕的主意(?).另一个想法是将功能的数量从12减少到类似4的东西.有没有其他方法来调整RTS以便我可以在空闲时保持进程从刻录到多个CPU周期?